iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0

現在來看一下如何解決一下 昨天 所提到的問題:將所有轉換一次處理,避免建立暫時用的 List。

LazyList

LazyList 就是 List laziness 的資料型態,老樣子 LazyList 在 Scala 原生庫中已有定義,但我們還是自行實作 LazyList 來練習,

import LazyList.*

enum LazyList[+A]:
  case Empty
  case Cons(h: () => A, t: () => LazyList[A])

object LazyList:
  def cons[A](hd: => A, tl: => LazyList[A]): LazyList[A] =
    lazy val head = hd
    lazy val tail = tl
    Cons(() => head, () => tail)

  def empty[A]: LazyList[A] = Empty

  def apply[A](as: A*): LazyList[A] =
    if as.isEmpty then empty
    else cons(as.head, apply(as.tail *))

在 enum 的定義上,跟 List 最大的不同是使用 () => A() => LazyList[A] 取代了 List 的 strict 值,

也使用了 cons function 來讓 LazyList 的初始化支持 laziness,最後就是使用 empty function 來 new Empty,讓 apply function 能更一致的做型別推斷;

high-order function 型別 () => A 等同於 [Function0[A]][https://scala-lang.org/api/3.x/scala/Function0.html] 這個 trait,先前我們用過的 high-order function (A, B) => C 等同於 Function2[A, B, C] ,以此類推最多支援到 Function22。

如果我們想走訪所有資料,請務必要留意調用 h() 以取得原始的值,例如我想取得 LazyList 的第一個值,並轉為 Option。

  def headOption: Option[A] = this match
    case Empty => None
    case Cons(h, _) => Some(h())

Exercise D10-1

實作 toList function 讓 LazyList 轉為 List。

 def toList: List[A]

Exercise D10-2

實作 take function,取得 LazyList 的前 n 個元素。

實作 drop function,丟掉 LazyList 的前 n 個元素。

def take(n: Int): LazyList[A] 
def drop(n: Int): LazyList[A]

Exercise D10-3

取得 LazyList 前面所有符合條件的元素,直到某個元素不符合。

def takeWhile(f: A => Boolean): LazyList[A]

明天在來介紹一下 LazyList 的進階用法吧!


Day 10 - Exercise answer


上一篇
Strictness 和 Laziness (1)
下一篇
Strictness 和 Laziness (3)
系列文
用 Scala 3 寫的 Functional Programming 會長什麼樣子?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言